package com.cy.pj;


import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
public class JdbcTests对数据库sql进行查询和写入数据操作 {
@Autowired
private DataSource dataSource;

//02--优化01写法，更灵活，用for循环一行代码获取所有字段列
    @Test
    void testSelectNotice02() throws SQLException {
        //1,获取连接
        Connection conn=dataSource.getConnection();

        //2,创建PreparedStatement
        //***注意的教训：要在from前面加个“空格”，和上一句隔开来，不然会报错
        String sql="select id,title,content,status,type,createdTime"+
                " from sys_notices where id>=?";
        PreparedStatement pstmt=conn.prepareStatement(sql);

        //3，发送sql语句，并返回结果集
        pstmt.setInt(1,2);
        //ResultSet rs=pstmt.execute();
        boolean flag=pstmt.execute();
        ResultSet rs=null;
        if(flag){
            rs=pstmt.getResultSet(); //返回的查询结果集
            ResultSetMetaData rsmd=rs.getMetaData();//获取结果集对应的的元数据--用来获取字段名和表名
            int columnCount=rsmd.getColumnCount(); //结果集有几列--6列(id,title,content,status,type,createdTime)

            //4,处理结果
            List<Map<String,Object>> list=new ArrayList<>();

            while(rs.next()){    //行映射，循环一次取一行，一行记录一个map对象
                Map<String,Object> map=new HashMap<>();
                for(int i=2;i<=columnCount;i++){  //循环一次取一行结果的值
                    String b=rsmd.getColumnLabel(i);//for循环取每列的--字段别名(没有别名就是默认的别名)
            map.put(b,rs.getObject(b));
            }
                /*map.put("id",rs.getInt("id"));
                map.put("title",rs.getString("title"));
                map.put("content",rs.getString("content"));
                map.put("status",rs.getString("status"));
                map.put("type",rs.getString("type"));
                map.put("createdTime",rs.getTimestamp("createdTime"));
                */
                list.add(map);
            }
            System.out.println(list);
        }
        rs.close();
        pstmt.close();
        conn.close();
    }

//01--添加查询通知的单元测试方法，代码如下：
@Test
 void testSelectNotice01() throws SQLException {
    //1,获取连接
    Connection conn=dataSource.getConnection();

    //2,创建PreparedStatement
   //***注意的教训：要在from前面加个“空格”，和上一句隔开来，不然会报错
    String sql="select id,title,content,status,type,createdTime"+
           " from sys_notices where id>=?";
    PreparedStatement pstmt=conn.prepareStatement(sql);
   //3，发送sql语句，并返回结果集
    pstmt.setInt(1,2);
   ResultSet rs=pstmt.executeQuery();//执行完sql语句返回的-- ResultSet结果集
   //4,处理结果
    List<Map<String,Object>> list=new ArrayList<>();
   //循环一次取一行，一行记录一个map对象
    while(rs.next()){       //
       Map<String,Object> map=new HashMap<>();
    map.put("id",rs.getInt("id"));
    map.put("title",rs.getString("title"));
        map.put("content",rs.getString("content"));
        map.put("status",rs.getString("status"));
        map.put("type",rs.getString("type"));
        map.put("createdTime",rs.getTimestamp("createdTime"));
        System.out.println(map);
    list.add(map);
    }
    rs.close();
    pstmt.close();
    conn.close();
}

    //在单元测试类中添加向表中写入数据的方法，关键代码如下：
//1，Statement写法--缺点：不安全，会sql注入
@Test
public void testJdbcTests() throws SQLException {
    //1,建立连接 (负责与数据库进行通讯)
    Connection conn=dataSource.getConnection();
    //2.创建 statement(sql 传送器->负责与将 sql 发送到数据库端)
    Statement stmt=conn.createStatement();
    //3,发送sql
String sql="insert into sys_notices(title,content,status,type,remark,createdUser)" +
        "values('MySq','Study MySql','0','1','Study...','admin')";
stmt.execute(sql);
System.out.println("Ad");

    //4,处理结果
    //5，释放资源
    stmt.close();
    conn.close();
}

    //在类中定义向表中写入数据的另一种方式，代码如下：
//2.常用的--占位符的形式--安全性高，编写简单，性能好(加载一次有缓存)
    @Test
    public void testJdbcTests2() throws SQLException {
        //1,建立连接 (负责与数据库进行通讯)
        Connection conn=dataSource.getConnection();

        //3,发送sql
        String sql="insert into sys_notices(title,content,status,type,remark,createdUser)" +
                "values(?,?,?,?,?,?)";
        PreparedStatement stmt=conn.prepareStatement(sql);
        stmt.setString(1, "Hikaricp");
        stmt.setString(2, "Study");
        stmt.setString(3, "0");
        stmt.setString(4, "1");
        stmt.setString(5, "Study...");
        stmt.setString(6, "jasion");
        stmt.execute();

        //4,处理结果
        //5，释放资源
        stmt.close();
        conn.close();
    }
}
